using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using Habanero.Base.Exceptions;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic.Commands
{
    [TestFixture]
    public class TestRenameClassCommand
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        [Test]
        public void TestApply()
        {
            //---------------Set up test pack-------------------
            DMClass @class = TestUtilsShared.CreateSavedDMClass();
            @class.ClassNameBO = "OriginalName";
            @class.Save();
            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";

            //---------------Execute Test ----------------------
            ICommand command = commandFactory.CreateRenameClass(@class, newName);
            command.Apply();

            //---------------Test Result -----------------------
            Assert.AreEqual(newName, @class.ClassNameBO);

            //---------------Tear Down -------------------------          
        }

        [Test]
        public void TestApply_Failure_Duplicate()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            DMAssembly assembly2 = dmSolution.CreateAssembly("Assembly2");
            assembly2.Save();
            const string classname = "ClassName";
            DMClass class1 = assembly2.CreateClass(classname);
            class1.Save();
            const string originalclaasname = "OriginalClaasName";
            DMClass class2 = assembly2.CreateClass(originalclaasname);
            class2.Save();
            ICommandFactory commandFactory = new CommandFactory();

            //---------------Execute Test ----------------------
            try
            {
                ICommand command = commandFactory.CreateRenameClass(class2, classname);
                command.Apply();
                Assert.Fail("Shouldn't save successfully as there is a duplicate class");
            }
            catch (HabaneroApplicationException ex)
            {
                StringAssert.Contains("already exists with the same identifier:", ex.Message);
            }
            Assert.AreEqual(originalclaasname, class2.ClassNameBO);

            //---------------Tear Down -------------------------          
        }

        [Test]
        public void Test_Revert()
        {
            DMClass @class = TestUtilsShared.CreateSavedDMClass();
            const string originalname = "OriginalName";
            @class.ClassNameBO = originalname;
            @class.Save();
            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";
            ICommand command = commandFactory.CreateRenameClass(@class, newName);
            command.Apply();

            //---------------Assert preconditions---------------
            Assert.AreEqual(newName, @class.ClassNameBO);
            //---------------Execute Test ----------------------
            command.Revert();
            //---------------Test Result -----------------------
            Assert.AreSame(originalname, @class.ClassNameBO);
            //---------------Tear Down -------------------------          
        }

        [Test]
        public void Test_Revert_Fail_Duplicate()
        {
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            DMAssembly assembly = solution.CreateAssembly("Assembly1");
            assembly.Save();
            string originalname = "OriginalName";
            DMClass class1 = assembly.CreateClass(originalname);

            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";

            ICommand command = commandFactory.CreateRenameClass(class1, newName);
            command.Apply();

            DMClass class2 = assembly.CreateClass(originalname);
            class2.Save();

            //---------------Assert preconditions---------------
            Assert.AreEqual(newName, class1.ClassNameBO);
            //---------------Execute Test ----------------------
            try
            {
                command.Revert();
                Assert.Fail("Revert should fail as there is now a duplicate class");
            }
            //---------------Test Result -----------------------
            catch (HabaneroApplicationException)
            {
                Assert.AreSame(newName, class1.ClassNameBO);
            }

            //---------------Tear Down -------------------------          
        }

    }
}
